package com.omega.encryptedsql.manager;

/**
 * @author omega
 * @description: TODO
 * @date 2025/7/10
 */
import com.omega.encryptedsql.annotation.SensitiveField;
import com.omega.encryptedsql.properties.EncryptProperties;
import com.omega.encryptedsql.utils.AesEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.Base64;


@Component
public class EncryptorManager {

    private final KeyManager keyManager;

    private static final EncryptProperties encryptProperties = new EncryptProperties();

    @Autowired
    public EncryptorManager(KeyManager keyManager) {
        this.keyManager = keyManager;
    }

    public String encrypt(String plaintext) throws Exception {
        return encrypt(plaintext, "personal");
    }

    public String encrypt(String plaintext, String keyId) throws Exception {
        String secretKey = keyManager.getKey(keyId);
        return AesEncryptor.encrypt(plaintext, secretKey);
    }

    public String decrypt(String ciphertext) throws Exception {
        // 自动检测密钥ID（从密文格式中提取）
        return decrypt(ciphertext, "personal");
    }

    public String decrypt(String ciphertext, String keyId) throws Exception {
        String secretKey = keyManager.getKey(keyId);
        return AesEncryptor.decrypt(ciphertext, secretKey);
    }

    public String getKeyIdForField(Field field) {
        if (field.isAnnotationPresent(SensitiveField.class)) {
            SensitiveField annotation = field.getAnnotation(SensitiveField.class);
            return annotation.keyId();
        }
        return "personal";
    }

    /**
     * 检测是否可能是加密数据
     */
    public boolean isLikelyEncrypted(String value) {
        if (!encryptProperties.isAutoDetect()) {
            return false;
        }

        // 检测加密数据特征
        if (value == null || value.length() < 24) {
            return false;
        }

        try {
            byte[] decoded = Base64.getDecoder().decode(value);
            // 加密数据通常包含IV和密文，长度大于IV长度
            return decoded.length > 12;
        } catch (Exception e) {
            return false;
        }
    }
}
